<script setup lang="ts">
import { MoreOutlined } from '@ant-design/icons-vue'
import type { MenuProps } from 'ant-design-vue'
import type { MenuReq, MenuResp } from '~/api/setting/model/menu.ts'
import {
  queryCheckedMenuTreeListByPermissionId,
} from '~/api/setting/menu.ts'

const props = defineProps({
  permissionData: Object,
})

const emits = defineEmits(['onItemSelect'])

const expandedKeys = ref<(string | number)[]>([])
const searchValue = shallowRef('')
const autoExpandParent = ref<boolean>(true)

const loading = shallowRef(false)
const treeData = shallowRef<any[]>([])

/**
 * 初始化菜单树数据
 */
async function init() {
  if (loading.value) {
    return
  }
  loading.value = true
  try {
    const menuReq: MenuReq = {
      permissionId: props.permissionData?.id,
    }
    const menuTreeData = await queryCheckedMenuTreeListByPermissionId(menuReq)

    generateList(menuTreeData)
    treeData.value = menuTreeData
    getAllParentKeys(treeData.value, expandedKeys.value)
  } catch (e) {
    console.log(e)
  } finally {
    loading.value = false
  }
}

/**
 * 菜单树展开菜单列表
 */
const dataList: MenuResp[] = []
/**
 * 递归菜单树展开菜单列表
 * @param tree 菜单树
 */
function generateList(tree: MenuResp[]) {
  for (let i = 0; i < tree?.length; i++) {
    const node = tree[i]
    dataList.push(node)
    if (node.children) {
      generateList(node.children)
    }
  }
}

/**
 * 获取菜单名称模糊查询到的树节点
 * @param key 菜单名称
 * @param tree 菜单树
 */
function getParentKey(key: string | number, tree: MenuResp[]): string | number {
  let parentKey: any
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      if (node.children.some(item => item.id === key)) {
        parentKey = node.id
      } else if (getParentKey(key, node.children)) {
        parentKey = getParentKey(key, node.children)
      }
    }
  }
  return parentKey
}

/**
 * 获取全部的父级菜单
 *
 * @param tree 菜单树形菜单
 * @param allParentKeys 全部的父级节点
 */
function getAllParentKeys(tree: MenuResp[], allParentKeys: (string | number)[]) {
  if (!tree) {
    return
  }

  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      if (node.id) {
        allParentKeys.push(node.id)
      }
      getAllParentKeys(node.children, allParentKeys)
    }
  }
}

async function onSearch() {

}

/**
 * 树展开
 * @param keys 展开父级节点集合
 */
function onExpand(keys: (string | number)[]) {
  expandedKeys.value = keys
}

/**
 * 树展开折叠
 * @param e
 */
const handleMenuClick: MenuProps['onClick'] = (e) => {
  expandedKeys.value = []
  if (e.key === 'expandAll') {
    getAllParentKeys(treeData.value, expandedKeys.value)
  }
}

/**
 * 点击树节点
 * @param selectedKeys
 * @param { selected, node }
 */

function onItemSelect(selectedKeys, { selected, node }) {
  console.log('onItemSelect', selectedKeys, node)
  emits('onItemSelect', selected, node)
}

watch(searchValue, (value) => {
  expandedKeys.value = dataList
    .map((item: MenuResp[][number]) => {
      if (item?.menuTitle?.includes(value) && item.id) {
        return getParentKey(item.id, treeData.value)
      }
      return ''
    })
    .filter((item, i, self) => item && self.indexOf(item) === i)
  searchValue.value = value
  autoExpandParent.value = true
})

onMounted(() => {
  init()
})
</script>

<template>
  <a-card title="菜单">
    <template #extra>
      <a-flex gap="small" align="center">
        <a-input-search
          v-model:value="searchValue"
          placeholder="搜索"
          style="width: 180px"
          allow-clear
          @search="onSearch"
        />
        <a-dropdown>
          <template #overlay>
            <a-menu @click="handleMenuClick">
              <a-menu-item key="expandAll">
                展开全部
              </a-menu-item>
              <a-menu-item key="unExpandAll">
                折叠全部
              </a-menu-item>
            </a-menu>
          </template>
          <MoreOutlined :font-size="6" />
        </a-dropdown>
      </a-flex>
    </template>
    <a-tree
      v-if="autoExpandParent && treeData && treeData.length > 0"
      :tree-data="treeData"
      :field-names="{ key: 'id', title: 'menuTitle' }"
      :expanded-keys="expandedKeys"
      :auto-expand-parent="autoExpandParent"
      @expand="onExpand"
      @select="onItemSelect"
    >
      <template #title="{ menuTitle }">
        <span v-if="menuTitle.indexOf(searchValue) > -1">
          {{ menuTitle.substring(0, menuTitle.indexOf(searchValue)) }}
          <span style="color: #f50">{{ searchValue }}</span>
          {{ menuTitle.substring(menuTitle.indexOf(searchValue) + searchValue.length) }}
        </span>
        <span v-else>{{ menuTitle }}</span>
      </template>
    </a-tree>
  </a-card>
</template>

<style scoped lang="less">

</style>
